<!--
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2024-04-29 10:01:19
 * @LastEditors: icymoon911 icymoon911@163.com
 * @LastEditTime: 2024-11-13 14:46:31
 * @FilePath: \ken147258.topayClient\src\components\FormList\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <el-form
    ref="formRef"
    :model="initModel"
    class="searchForm"
    label-width="80px"
    v-bind="propInitForm.formAttrs"
  >
    <el-row important-ml-0 important-mr-0 :gutter="10" v-bind="propInitForm.rowAttrs">
      <template v-for="(item, index) in propInitForm.initKeys" :key="item.key">
        <el-col
          v-if="!item.hidden"
          :span="
            ['button', 'buttons'].includes(item.type)
              ? btnsSpan
              : item.type === 'input' && item.controlAttrs?.type === 'textarea'
              ? colSpan * propInitForm.rowAttrs.columnsNum
              : colSpan
          "
          :class="
            ['button', 'buttons'].includes(item.type) && !propInitForm.formAttrs.inline
              ? 'btn-sty'
              : ''
          "
        >
          <el-form-item
            w-full
            :prop="item.key"
            v-bind="item.formAttrs"
            v-show="(item.formAttrs || {}).show === false ? false : true"
          >
            <el-input
              v-if="item.type === 'input'"
              w-full
              maxlength="50"
              :placeholder="`请填写${item.formAttrs.label}`"
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            >
              <template v-if="item.appendTxt" #append>
                {{ item.appendTxt }}
              </template>
            </el-input>
            <el-input
              v-if="item.type === 'textarea'"
              type="textarea"
              w-full
              :rows="4"
              :placeholder="`请填写${item.formAttrs.label}`"
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            >
              <template v-if="item.appendTxt" #append>
                {{ item.appendTxt }}
              </template>
            </el-input>
            <el-autocomplete
              v-if="item.type === 'autocomplet'"
              w-full
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            />
            <el-checkbox-group
              v-if="item.type === 'checkbox-group'"
              w-full
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            >
              <el-checkbox
                v-for="option in item.options"
                :label="option.label"
                :value="option.value"
                :key="option.value"
              />
            </el-checkbox-group>
            <el-date-picker
              v-if="item.type === 'date-picker'"
              w-full
              type="datetime"
              :style="{ width: '100%' }"
              :placeholder="`请选择${item.formAttrs.label}`"
              v-model="initModel[item.key]"
              v-bind="{
                ...item.controlAttrs,
                // defaultTime: item.key === 'start_time' ? new Date(2000, 1, 1, 0, 0, 0) : (
                //   item.key === 'end_time' ? new Date(2000, 1, 1, 23, 59, 59) : ''
                // ),
              }"
              v-on="item.controlOn || {}"
            />
            <el-input-number
              v-if="item.type === 'input-number'"
              w-full
              v-model="initModel[item.key]"
              :placeholder="`请填写${item.formAttrs.label}`"
              v-bind="{
                precision: ['金额', '余额', '率', '押金'].some(
                  (label) => (item.formAttrs.label || '').indexOf(label) > -1
                )
                  ? 2
                  : 0,
                style: { width: '100%' },
                min: 0,
                ...item.controlAttrs,
              }"
              v-on="item.controlOn || {}"
            />
            <el-radio-group
              v-if="item.type === 'radio-group'"
              w-full
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            />
            <el-select
              v-if="item.type === 'select'"
              w-full
              v-model="initModel[item.key]"
              :placeholder="`请选择${item.formAttrs.label}`"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            >
              <el-option
                v-for="tItem in item.controlAttrs.options || item.options"
                :key="tItem.value"
                v-bind="tItem"
                v-on="tItem.controlOn || {}"
              />
            </el-select>
            <el-select-v2
              v-if="item.type === 'select-v2'"
              w-full
              :options="[]"
              :placeholder="`请选择${item.formAttrs.label}`"
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            />
            <el-switch
              v-if="item.type === 'switch'"
              w-full
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            />
            <el-time-picker
              v-if="item.type === 'time-picker'"
              w-full
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            />
            <el-transfer
              v-if="item.type === 'transfer'"
              w-full
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            />
            <el-cascader-panel
              v-if="item.type === 'cascader-panel'"
              w-full
              v-model="initModel[item.key]"
              v-bind="item.controlAttrs"
              v-on="item.controlOn || {}"
            >
              <template #default="{ node, data }">
                <el-tooltip
                  class="box-item"
                  effect="dark"
                  :content="data.label"
                  placement="top-start"
                >
                  <span class="el-cascader-node__label">{{ data.label }}</span>
                </el-tooltip>
              </template>
            </el-cascader-panel>
            <RangeInputs
              v-if="item.type === 'range-inputs'"
              w-full
              v-model="initModel[item.key]"
              :controlAttrs="item.controlAttrs.attrs"
              :controlOn="item.controlOn || [{}, {}]"
            >
            </RangeInputs>
            <UploadImage
              v-if="item.type === 'upload-img'"
              w-full
              v-model="initModel[item.key]"
              :controlAttrs="item.controlAttrs"
              :controlOn="item.controlOn || [{}, {}]"
            >
            </UploadImage>
            <AutoInput
              v-if="item.type === 'auto-input'"
              w-full
              v-model="initModel[item.key]"
              :controlAttrs="item.controlAttrs"
              v-on="item.controlOn || {}"
              :btns="item.btns"
            >
            </AutoInput>
            <div
              v-if="item.type === 'button'"
              w-full
              text-right
              v-bind="item.containerAttrs"
            >
              <el-button
                v-bind="item.controlAttrs"
                @click="(e: Event) => item.controlOn?.click && item.controlOn.click(e, formRef, initModel)"
              >
                {{ item.controlAttrs.text }}
              </el-button>
            </div>
            <div
              v-if="item.type === 'buttons'"
              w-full
              text-right
              v-bind="item.containerAttrs"
            >
              <el-button
                v-for="(tItem, index) in item.btns"
                :key="index"
                v-bind="tItem.controlAttrs"
                @click="(e: Event) => tItem.controlOn?.click && tItem.controlOn.click(e, formRef, initModel)"
              >
                {{ tItem.text }}
              </el-button>
            </div>
          </el-form-item>
        </el-col>
      </template>
    </el-row>
  </el-form>
</template>

<script setup lang="ts">
// 导入 watch 函数，用于监听数据变化
// 导入 Element-Plus 中的 FormInstance
// 导入 RangeInputs 组件
import { FormInstance, dayjs } from "element-plus";
import RangeInputs from "./components/RangeInputs/index.vue";
import AutoInput from "./components/AutoInput/index.vue";

// 定义选项
defineOptions({
  name: "FormList",
});

// 定义一个常量chunk，用于分片上传时每个分片的大小
const chunk = 24;

const props = defineProps({
  /**
   * 参数示例：
    // 表单标签位置
      // labelPosition: "right",
      formAttrs: {
        // 是否内联
        inline: true,
      },
      rowAttrs: {
        // 行内表单数量
        columnsNum: 4,
      },
      // 初始化表单字段
      initKeys: [
        {
          // 类型
          type: "select-v2",
          // 唯一标识
          key: "id",
          // 表单属性
          formAttrs: {
            label: "码商用户名",
          },
          // 控制属性
          controlAttrs: {
            // 提示文本
            placeholder: "请输入码商用户名",
            // 是否可清空
            clearable: true,
            filterable: true,
            options: [],
          },
          // 控制事件
          controlOn: {},
        },
        {
          // 类型
          type: "select-v2",
          // 唯一标识
          key: "parent_id",
          // 表单属性
          formAttrs: {
            label: "上级名称",
          },
          // 控制属性
          controlAttrs: {
            // 提示文本
            placeholder: "请输入上级名称",
            // 是否可清空
            clearable: true,
            filterable: true,
            options: [],
          },
          // 控制事件
          controlOn: {},
        },
        {
          // 类型
          type: "select",
          // 唯一标识
          key: "handle_order_status",
          // 表单属性
          formAttrs: {
            label: "开工状态",
          },
          // 控制属性
          controlAttrs: {
            placeholder: "请选择开工状态",
          },
          // 选项
          options: workStatusOptions,
        },
        // {
        //   // 类型
        //   type: "input-number",
        //   // 唯一标识
        //   key: "amount",
        //   // 表单属性
        //   formAttrs: {
        //     label: "层级",
        //   },
        //   // 控制属性
        //   controlAttrs: {
        //     // 提示文本
        //     placeholder: "请输入层级",
        //     // 是否可清空
        //     clearable: true,
        //     style: "width: 100%",
        //     min: 1,
        //   },
        //   // 控制事件
        //   controlOn: {},
        // },
        // {
        //   // 类型
        //   type: "select-v2",
        //   // 唯一标识
        //   key: "pro_id",
        //   // 表单属性
        //   formAttrs: {
        //     label: "产品名称",
        //   },
        //   // 控制属性
        //   controlAttrs: {
        //     // 提示文本
        //     placeholder: "请选择产品名称",
        //     // 是否可清空
        //     clearable: true,
        //     filterable: true,
        //     options: [],
        //   },
        //   // 控制事件
        //   controlOn: {},
        // },
        // {
        //   // 类型
        //   type: "date-picker",
        //   // 唯一标识
        //   key: "start_time",
        //   // 表单属性
        //   formAttrs: {
        //     label: "开始时间",
        //   },
        //   // 控制属性
        //   controlAttrs: {
        //     // 提示文本
        //     placeholder: "请选择开始时间",
        //     // 是否可清空
        //     clearable: true,
        //     style: {
        //       width: "100%",
        //     },
        //   },
        //   // 控制事件
        //   controlOn: {},
        // },
        // {
        //   // 类型
        //   type: "date-picker",
        //   // 唯一标识
        //   key: "end_time",
        //   // 表单属性
        //   formAttrs: {
        //     label: "结束时间",
        //   },
        //   // 控制属性
        //   controlAttrs: {
        //     // 提示文本
        //     placeholder: "请选择结束时间",
        //     // 是否可清空
        //     clearable: true,
        //     style: {
        //       width: "100%",
        //     },
        //   },
        //   // 控制事件
        //   controlOn: {},
        // },
        {
          // 类型
          type: "buttons",
          // 按钮
          btns: [
            {
              // 文本
              text: "搜索",
              // 控制属性
              controlAttrs: {
                // 类型
                type: "primary",
                icon: "search",
              },
              // 控制事件
              controlOn: {
                // 点击
                click: (e: Event, formRef: FormInstance, data: object) => {
                  formRef.validate((valid) => {
                    if (valid) {
                      tableDatasObj.value.paging.page = 1;

                      let tempData = { ...data };

                      // tempData.start_time = getTimestamp(data.start_time);
                      // tempData.end_time = getTimestamp(data.end_time);

                      tableDatasObj.value.queryParams = tempData;

                      handleQuery(tableDatasObj.value.paging);
                    }
                  });
                },
              },
            },
            {
              // 文本
              text: "重置",
              // 控制属性
              controlAttrs: {
                icon: "refresh",
              },
              // 控制事件
              controlOn: {
                // 点击
                click: resetQuery,
              },
            },
          ],
        },
      ],
    });
  */
  initForm: {
    type: Object,
    default: () => ({
      rowAttrs: {
        // 行内表单数量
        columnsNum: 4,
      },
      initKeys: [],
    }),
  },
  // formModel: {
  //   type: Object,
  //   default: () => ({}),
  // },
});

// 声明一个表单的ref
// const formRef = ref(ElForm);
// const formRef = ref(ElForm);
const formRef = defineModel("formRef", { type: Object, default: ElForm });
// const formRef = ref<FormInstance>();

// 定义一个名为defineEmits的函数，该函数接受一个参数，用于创建一个emit对象
// const emit = defineEmits(["update:formRef", "update:formModel"]);

// 定义一个名为watch的函数，该函数接受两个参数，一个参数为formRef，另一个参数为一个函数，用于在formRef发生变化时触发emit函数
// watch(
//   formRef,
//   () => {
//     // 在formRef发生变化时，触发emit函数，参数为formRef
//     emit("update:formRef", formRef);
//   },
//   { deep: true }
// );

// 初始化一个ref，用于存储表单的初始化字段
// 重新加载值
function reloadValues(v1, v2) {
  // 过滤出initKeys中的key
  let keyArrs = (v1 || []).filter((item: { key: string }) => item.key) || [];

  // 如果keyArrs的长度不为0
  if (keyArrs.length) {
    // 遍历keyArrs，将每个item.key的值赋值给initModel.value
    keyArrs.map((item) => {
      let val = "";
      if (["start_time"].includes(item.key)) {
        // initModel.value[item.key] = item.value || dayjs().startOf("date").toDate();
      } else if (["end_time"].includes(item.key)) {
        // initModel.value[item.key] = item.value || dayjs().endOf("date").toDate();
      } else {
        // val = item.value;
        if (!initModel.value[item.key]) {
          initModel.value[item.key] = item.value;
        }
      }

      // if (initModel.value[item.key] !== val) {
      // if (
      //   (v1 || []).find((item1) => item1.key === item.key)?.value !==
      //   (v2 || []).find((item1) => item1.key === item.key)?.value
      // ) {
      //   initModel.value[item.key] = val;
      // }
      // initModel.value[item.key] = val;

      return item.key;
    });
  } else {
    // 如果keyArrs的长度为0，将initModel.value设置为空对象
    initModel.value = {};
  }
}
// const modelValue = defineEmits(["update:modelValue"]);

// const initModel = ref(tempObj);
// const initModel = ref({});

const getTimestamp = inject("getTimestamp");

const initModel = defineModel("formModel", {
  type: Object,
  default: ElForm,
  // get(obj) {
  //   Object.entries(obj).map(([key, value]) => {
  //     if (value instanceof Date) {
  //       obj[key] = getTimestamp(value);
  //     }
  //   });

  //   return obj;
  // },
});

// const initModel = useVModel(props, "modelValue", emit);;

// const model = defineModel({ default: initModel.value })
// const props1 = defineProps<{
//   modelValue: Object
// }>()
// const emit1 = defineEmits(['update:modelValue'])

// const data = useVModel(props1, 'modelValue', emit1)

// watch(
//   initModel,
//   () => {
//     // 在initModel发生变化时，触发emit函数，参数为initModel
//     // emit("update:formModel", initModel.value);

//     console.log("initModel", initModel.value['status']);
//   },
//   {
//     deep: true,
//     immediate: true,
//   }
// );

// const initKeyCom = computed(() => {

// });

// 获取表单的列数
// const columnsNum = props.initForm.rowAttrs.columnsNum;
const propInitForm = toRef(props, "initForm");

// 监听initKeys的值的变化，当发生变化时，调用reloadValues函数
watch(
  () => propInitForm.value.initKeys,
  (v1, v2) => {
    // const tempV1 = (v1 || []).map((item) => ({ key: item.key, value: item.value }));
    // const tempV2 = (v2 || []).map((item) => ({ key: item.key, value: item.value }));

    // if (JSON.stringify(tempV1) !== JSON.stringify(tempV2)) {
    reloadValues(v1, v2);
    // }
  },
  {
    deep: true,
    immediate: true,
  }
);
// reloadValues();

// 计算每行的列数
const colSpan = computed(() => {
  return chunk / propInitForm.value.rowAttrs.columnsNum;
});

// 计算按钮的列数
const btnsSpan = computed(() => {
  let result = chunk;
  const remainder =
    (
      props.initForm.initKeys.filter(
        (item: { key: string }) => item.key || item.type === "empty"
      ) || []
    ).length % propInitForm.value.rowAttrs.columnsNum;

  // 如果存在余数，则按钮的列数应为每行列数减去余数
  if (!!remainder) {
    result = chunk - remainder * colSpan.value;
  }

  return result;
});
</script>

<style lang="scss" scoped>
:deep(.el-form-item__content) {
  // padding-right: 12px;
}

:deep(.btn-sty) {
  .el-form-item {
    height: 100%;
    padding-bottom: 18px;

    .el-form-item__content {
      height: 100%;

      & > div {
        height: 100%;
        display: flex;
        align-items: flex-end;
        justify-content: flex-end;
      }
    }
  }
}
</style>
